/*
    Copyright (C) 2019 Zongming Liu <1849059316@qq.com>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#ifndef Interface_h__
#define Interface_h__

#include <SkyGameEngine.h>

using namespace SkyEngine2d;

#include "Player.h"

class MainPlayer;
class IGameLevelScene;

class IMainPlayerState
{
public:
    enum class State
    {
        StaticState,  //角色在站立状态
        MoveState,    //角色在行走
        AttackStateA, //在攻击状态A
        AttackStateB, //在攻击状态B
    };

    virtual void execute(MainPlayer *c) = 0;
    virtual void enter(MainPlayer *c) = 0;
    virtual void leave(MainPlayer *c) = 0;
    virtual void reset() = 0;
    virtual void init() = 0;
    virtual State getCurrentState() const = 0;
};

class IPlayer
{
public:
    enum class Direction
    {
        Up,
        Down,
        Left,
        Right,
        None
    };

    enum class ModifyHpType
    {
        Nomale,   //普通攻击
        Critical, //暴击
        None,
    };

    //获取最大的血量
    virtual int getMaxHp() const = 0;
    //修改血量
    virtual void modifyHp(int dt, ModifyHpType type) = 0;
    //获取当前的血量
    virtual int getCurrentHp() const = 0;
    //是否死亡
    virtual bool isDeath() const = 0;
    //获取矩形区域
    virtual Rect getRect() = 0;
    //获取当前的位置
    virtual Vector2 getPosition() = 0;
    //设置前后顺序
    virtual void setOrder(int order) = 0;
    //通知 miss
    virtual void notifyMiss() = 0;

public:
    //设置人物ID
    void setId(int id) { m_id = id; }
    //获取ID
    int getId() const { return m_id; }
    //获取场景
    const IGameLevelScene *getGameScene() const { return m_scene; }
    //设置场景
    void setGameScene(IGameLevelScene *s) { m_scene = s; }

private:
    int m_id;
    IGameLevelScene *m_scene;
};

class IMainPlayer
    : public IPlayer
{
public:
    virtual bool init(Node *parent) = 0;
    virtual void move(IPlayer::Direction dir) = 0;
    virtual void run(float dt) = 0;
    virtual void stand(bool isCompel = false) = 0;
    virtual void useSkill(int skill_id) = 0;
    virtual void death() = 0;
};

class IGameLevelScene
{
public:
    //获取玩家的位置
    virtual Vector2 getMainPlayerPosition() = 0;
    //获取玩家的血量
    virtual int getMainPLayerHp() = 0;
    //获取玩家的矩形
    virtual Rect getMainPlayerRect() = 0;
    //获取玩家
    virtual IPlayer *getMainPlayer() = 0;
    //申请一个矩形的标识ID
    virtual int allocateRectId() = 0;
    //修改一个ID 的 矩形
    virtual void modifyRectById(int id, const Rect &rect) = 0;
    //删除一个ID
    virtual void freeRect(int id) = 0;
    //判断是否会和已知的矩形发生碰撞
    virtual bool isCollision(int self_id, const Rect &self_rect) const = 0;
    //判断直线是否会和某个矩形相交
    virtual bool isIntersect(int self_id, const Line &self_line, int *intersect_id) const = 0;
};

class MonsterMachine;

class IMonster
    : public IPlayer
{
public:
    enum class MonsterType
    {
        MonsterTypeA,
        MonsterTypeB,
        MosterTypeBoos
    };
    virtual bool init(MonsterType type, Node *parent, IGameLevelScene *g) = 0;
    virtual void stand() = 0;
    virtual void attack(IPlayer *player) = 0;
    virtual bool canAttack(const Rect &main_player_rect) = 0;
    virtual void moveTo(const Vector2 &pos) = 0;
    virtual void run(float dt) = 0;
    virtual void Bruise() = 0;
    virtual MonsterMachine *getMonsterMachine() = 0;
};

class IMonsterDate
{
public:
    //速度
    virtual float getSpeed() = 0;
    //血量上限
    virtual int getTotalHp() = 0;
    //普通伤害
    virtual int getNormalDamage() = 0;
    //暴击率
    virtual float getCritical() = 0;
    //攻击距离
    virtual float getAttackDistance() = 0;
    //自身的模型矩形  相对与 精灵矩形
    virtual Rect getShapeRect() = 0;
};

class IGameLevelInfo
{
public:
    //获取怪物A的数量
    virtual int getMonsterACount() const = 0;
    //获取怪物B的数量
    virtual int getMonsterBCount() const = 0;
    //获取Boos的数量
    virtual int getMonsterBoosCount() const = 0;
    //获取当前的关卡级别
    virtual int getLevel() const = 0;
};

#endif // Interface_h__
